/**
	*****************************************************************************
	* @file     cmem7_eth.h
	*
	* @brief    CMEM7 ethernet header file
	*
	*
	* @version  V1.0
	* @date     3. September 2013
	*
	* @note               
	*           
	*****************************************************************************
	* @attention
	*
	* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
	* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
	* TIME. AS A RESULT, CAPITAL-MICRO SHALL NOT BE HELD LIABLE FOR ANY DIRECT, 
	* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
	* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
	* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
	*
	* <h2><center>&copy; COPYRIGHT 2013 Capital-micro </center></h2>
	*****************************************************************************
	*/
	
#ifndef __CMEM7_ETH_H
#define __CMEM7_ETH_H

#ifdef __cplusplus
 extern "C" {
#endif

#include "cmem7.h"
#include "cmem7_conf.h"


#define ETH_SPEED_10M               0x0
#define ETH_SPEED_100M              0x1
#define ETH_SPEED_1000M             0x2

#define IS_ETH_SPEED(SPEED)    			(((SPEED) == ETH_SPEED_10M)  || \
                                     ((SPEED) == ETH_SPEED_100M) || \
																		 ((SPEED) == ETH_SPEED_1000M))

#define ETH_DUPLEX_HALF             0x0
#define ETH_DUPLEX_FULL             0x1

#define IS_ETH_DUPLEX(DUPLEX)  			(((DUPLEX) == ETH_DUPLEX_HALF) || \
																		 ((DUPLEX) == ETH_DUPLEX_FULL))
																			
#define ETH_INT_TX_COMPLETE_FRAME		0x0001
#define ETH_INT_TX_STOP             0x0002
#define ETH_INT_TX_BUF_UNAVAI       0x0004
#define ETH_INT_RX_COMPLETE_FRAME   0x0040
#define ETH_INT_RX_BUF_UNAVAI       0x0080
#define ETH_INT_RX_STOP             0x0100
#define ETH_INT_BUS_FATAL_ERROR     0x2000
#define ETH_INT_ALL                 (ETH_INT_TX_COMPLETE_FRAME | \
                                     ETH_INT_TX_STOP           | \
																		 ETH_INT_TX_BUF_UNAVAI     | \
																		 ETH_INT_RX_COMPLETE_FRAME | \
																		 ETH_INT_RX_BUF_UNAVAI     | \
																		 ETH_INT_RX_STOP           | \
																		 ETH_INT_BUS_FATAL_ERROR)

#define IS_ETH_INT(INT)             (((INT) & ~ETH_INT_ALL) == 0)


typedef struct
{
  BOOL ETH_LinkUp;                   /*!< If ETH is linked up and it can be retrieved from PHY */																	  
	uint8_t ETH_Speed;                 /*!< speed of ETH, refer as ETH_SPEED_XXX                 */
  uint8_t ETH_Duplex;                /*!< duplex mode of ETH, refer as ETH_DUPLEX_XXX 				 */
	BOOL ETH_RxEn;                     /*!< Rx enable                                            */
	BOOL ETH_TxEn;                     /*!< Tx enable                                            */
	BOOL ETH_ChecksumOffload;          /*!< Checksum offload enable                              */
	BOOL ETH_JumboFrame;               /*!< Jumbo Frame Enable                                   */
	uint8_t ETH_MacAddr[6];                         
} ETH_InitTypeDef;

typedef struct { 
	union {
    uint32_t  TX0;
		
		struct {
			uint32_t 								: 25;
			uint32_t TTSE           :  1; 	 /*!< enables IEEE1588 hardware timestamping while first segment */
			uint32_t 								:  2;
			uint32_t FS           	:  1; 	 /*!< first segment flag                                    */
			uint32_t LS           	:  1; 	 /*!< last segment flag                                     */
			uint32_t 		           	:  2; 
		} TX0_b;
	} TX_0;
	
	union {
    uint32_t  TX1;
		
		struct {
			uint32_t SIZE						: 13; 	 /*!< buffer size                                           */
			uint32_t                : 19;
		} TX1_b;
	} TX_1;
	
	uint32_t bufAddr;
	uint32_t nextDescAddr;
  uint64_t reserved;
	uint64_t timeStamp;									 /*!< time stamp while last segment                         */
} ETH_TX_DESC;

typedef struct { 
	union {
    uint32_t  RX0;
		
		struct {
			uint32_t 								:  7;
			uint32_t TTSE           :  1; 	 /*!< timestamp available while last segment                */
			uint32_t LS           	:  1; 	 /*!< last segment flag                                     */
			uint32_t FS           	:  1; 	 /*!< first segment flag                                    */
			uint32_t 		           	:  6; 
			uint32_t FL           	: 14; 	 /*!< frame length while last segment                       */
			uint32_t 		           	:  2;
		} RX0_b;
	} RX_0;
	
	union {
    uint32_t  RX1;
		
		struct {
			uint32_t SIZE						: 13; 	 /*!< buffer size                                           */
			uint32_t                : 19;
		} RX1_b;
	} RX_1;
	
	uint32_t bufAddr;
	uint32_t nextDescAddr;
  uint64_t reserved;
	uint64_t timeStamp;									 /*!< time stamp while the last segment                     */
} ETH_RX_DESC;

uint32_t ETH_PhyRead(uint32_t phyAddr, uint32_t phyReg);
void ETH_PhyWrite(uint32_t phyAddr, uint32_t phyReg, uint32_t data);

BOOL ETH_Init(ETH_InitTypeDef *init);
void ETH_EnableInt(uint32_t Int, BOOL enable);
BOOL ETH_GetIntStatus(uint32_t Int);
void ETH_ClearInt(uint32_t Int);
void ETH_GetMacAddr(uint8_t *mac);

BOOL ETH_SetTxDescList(ETH_TX_DESC *list);
void ETH_StartTx(void);
void ETH_StopTx(void);
void ETH_ResumeTx(void);
ETH_TX_DESC *ETH_AcquireFreeTxDesc(void);
BOOL ETH_IsFreeTxDesc(ETH_TX_DESC *desc);
void ETH_ReleaseTxDesc(ETH_TX_DESC *desc);

BOOL ETH_SetRxDescList(ETH_RX_DESC *list);
void ETH_StartRx(void);
void ETH_StopRx(void);
void ETH_ResumeRx(void);
ETH_RX_DESC *ETH_AcquireFreeRxDesc(void);
BOOL ETH_IsFreeRxDesc(ETH_RX_DESC *desc);
void ETH_ReleaseRxDesc(ETH_RX_DESC *desc);

#ifdef __cplusplus
}
#endif

#endif /* __CMEM7_ETH_H */

